package Creche.Bd;

import java.util.ArrayList;
import java.util.Iterator;

import javax.jdo.Extent;
import javax.jdo.PersistenceManager;
import javax.jdo.Transaction;

import CodeAdmin.Code;
import Creche.Admin.Administrateur;
import Creche.Donnees.Modification;
import Creche.Main.Creche;
import Creche.Personne.Personne;

/**
 * Classe permettant de requetter jdo affin d'obtenir la liste des 
 * des cr�ches enregistr�es ou une cr�che pr�cise
 *
 */
public class BD {

	public BD() {
	}
	
	/**
	 * Sauvegarde d'un objet dans jdo 
	 * On pourra y sauvegarder nimporte quel type d'objet
	 * @param sauv, un Object � sauvegarder dans jdo
	 */
	public void estPersistent(Object sauv) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Transaction tx = pm.currentTransaction();
		try
		{
		    tx.begin();
		    if (sauv != null) {
		    	pm.makePersistent(sauv);
		    }
		    tx.commit();
		}
		finally
		{
		    if (tx.isActive())
		    {
		        tx.rollback();
		    }
		    pm.close();
		}
	}
	
	/**
	 * Sauvegarde d'objets dans jdo 
	 * On pourra y sauvegarder nimporte quel type d'objet
	 * @param sauv, Une ArrayList d'object � sauvegarder dans jdo
	 */
	public void estPersistents(ArrayList<Creche> sauv) {
		for(int i = 0; i < sauv.size();i++) {
			estPersistent(sauv.get(i));
		}
	}
	
	/**
	 * Obtention de toutes les cr�ches enregistr�es dans jdo
	 * on chargera toutes les cr�ches dans la base de donn�es et on appelera
	 * tous les objets dans un objet Creche � l'aide des getters disponibles
	 * afin qu'ils soient charger avec
	 * @return une ArrayList de Creche
	 */
	public ArrayList<Creche> getCreches() {
		ArrayList<Creche> resultat = new ArrayList<Creche>();
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Creche courrante = null;;
		Extent<Creche> e = pm.getExtent(Creche.class,true);
		Iterator<Creche> it = e.iterator();
		while (it.hasNext()) {
			courrante = (Creche) it.next();
			courrante.getAdresse();
			courrante.getSeulementDonnees();
			courrante.getActu();
			courrante.getListPers();
			resultat.add(courrante);
			
			for (Personne pers : courrante.getListPers()) {
				pers.getAdresse();
			}
		}
		pm.close();
		return resultat;
	}
	
	/**
	 * Obtention d'une cr�che grace � son nom
	 * ob parcourra toutes les cr�ches en bd jusqu'� trouver la bonne
	 * @param label, nom de la cr�che � chercher forme ville:nom
	 * @return la creche resultat ou null si elle n'existe pas
	 */
	public Creche getCreche(String label) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Creche courrante = null;
		Creche resultat = null;
		Extent<Creche> e = pm.getExtent(Creche.class,true);
		Iterator<Creche> it = e.iterator();
		while (it.hasNext() && resultat == null) {
			courrante = (Creche) it.next();
			courrante.getAdresse();
			courrante.getSeulementDonnees();
			courrante.getActu();
			courrante.getListPers();
			
			for (Personne pers : courrante.getListPers()) {
				pers.getAdresse();
			}
			
			if ((courrante.getAdresse().getVille()+":"+courrante.getNom()).equals(label)){
				resultat = courrante;
			}
		}
		pm.close();
		return resultat;
	}
	
	
	
	/**
	 * Obtention d'une creche par son nom et sa ville
	 * @String nom
	 * @String ville
	 * @return la creche resultat ou null si elle n'existe pas
	 */
	
	public Creche getCreche(String nom, String ville) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Creche courrante = null;
		Creche resultat = null;
		Extent<Creche> e = pm.getExtent(Creche.class,true);
		Iterator<Creche> it = e.iterator();
		while (it.hasNext() && resultat == null) {
			courrante = (Creche) it.next();
			courrante.getAdresse();
			courrante.getSeulementDonnees();
			courrante.getActu();
			courrante.getListPers();
			
			for (Personne pers : courrante.getListPers()) {
				pers.getAdresse();
			}
			
			if ((courrante.getAdresse().getVille()).equals(ville) && (courrante.getNom()).equals(nom)){
				resultat = courrante;
			}
		}
		pm.close();
		return resultat;
	}
	
	/**
	 * Fonction de test ne durera pas, permet de supprimer toutes les cr�ches
	 * en bd
	 */
	public void remove(){
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Creche courrante = null;
		Extent<Creche> e = pm.getExtent(Creche.class,true);
		Iterator<Creche> it = e.iterator();
		while (it.hasNext()) {
			courrante = (Creche) it.next();
			courrante.getAdresse();
			courrante.getSeulementDonnees();
			courrante.getActu();
            pm.deletePersistent(courrante);
		}
		pm.close();
	}
	
	/**
	 * Supprime tous les objets dans la base de donn�es
	 */
	public void removeAll()
	{
		remove();
		removeAllModif();
		removeAllAdmin();
		removeAllPers();
		removeAllCode();
	}
	
	/**
	 * Suppression d'une modification on va  parcourrir les modifs
	 * jusqu'� trouver la bonne modification et la supprimer
	 * @param modif, le nom de la Modification � supprimer
	 */
	public void removeModif(String modif) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Modification courrante = null;
		Extent<Modification> e = pm.getExtent(Modification.class,true);
		Iterator<Modification> it = e.iterator();
		while (it.hasNext()) {
			courrante = (Modification) it.next();
			if (courrante.getIdModif().equals(modif)) {
	            pm.deletePersistent(courrante);
			}
		}
		pm.close();
	}
	
	/**
	 * Suppression de toutes les modifications
	 */
	public void removeAllModif() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Modification courrante = null;
		Extent<Modification> e = pm.getExtent(Modification.class,true);
		Iterator<Modification> it = e.iterator();
		while (it.hasNext()) {
			courrante = (Modification) it.next();
            pm.deletePersistent(courrante);
		}
		pm.close();
	}
	
	/**
	 * Obtention de la liste de toute les modifications effectu�es
	 * @return une liste de Modification
	 */
	public ArrayList<Modification> getModif() {
		ArrayList<Modification> resultat = new ArrayList<Modification>();
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Extent<Modification> e = pm.getExtent(Modification.class,true);
		Iterator<Modification> it = e.iterator();
		while (it.hasNext()) {
			resultat.add((Modification) it.next());
		}
		pm.close();
		return resultat;
	}
	
	/**
	 * Indique si un administrateur est déjà inscrit dans la bd
	 * @param l'administrateur recherché
	 * @return vrai si l'administrateur existe
	 */
	public boolean canRegisterAdmin(Administrateur admin) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Administrateur courrant = null;
		boolean resultat = false;
		
		Extent<Administrateur> e = pm.getExtent(Administrateur.class,true);
		Iterator<Administrateur> it = e.iterator();
		
		while (it.hasNext() && resultat == false) {
			courrant = (Administrateur) it.next();
			if (courrant.getEmail().equals(admin.getEmail())) {
				resultat = true;
			}
		}
		
		pm.close();
		return resultat;
	}
	
	/**
	 * Retourne une ArrayList contenant un booléen indiquant si un admin
	 * existe en bd est si c'est le cas, l'ajoute dans l'ArrayList
	 * @param l'administrateur recherché
	 * @return ArrayList (booléen, admin)
	 */
	public ArrayList<Object> canConnectAdmin(Administrateur admin) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		ArrayList<Object> al = new ArrayList<Object>();
		Administrateur courrant = null;
		boolean resultat = false;
		
		Extent<Administrateur> e = pm.getExtent(Administrateur.class,true);
		Iterator<Administrateur> it = e.iterator();
		
		while (it.hasNext() && resultat == false) {
			courrant = (Administrateur) it.next();
			if (courrant.getEmail().equals(admin.getEmail()) &&
				courrant.getIdentifiant().equals(admin.getIdentifiant()) &&
				courrant.getMotDePasse().equals(admin.getMotDePasse())) {
				
				resultat = true;
				al.add(resultat);
				al.add(courrant);
			}
		}
		
		pm.close();
		al.add(resultat);
		al.add(courrant);
		
		return al;
	}
	
	/**
	 * Obtention d'un administrateur grâce à son email
	 * @param email de l'administrateur recherché
	 * @return l'administrateur ou null s'il n'existe pas
	 */
	public Administrateur getAdmin(String email) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Administrateur courrant = null;
		Administrateur resultat = null;
		
		Extent<Administrateur> e = pm.getExtent(Administrateur.class,true);
		Iterator<Administrateur> it = e.iterator();
		
		while (it.hasNext() && resultat == null) {
			courrant = (Administrateur) it.next();
			if (courrant.getEmail().equals(email)) {
				resultat = courrant;
			}
		}
		
		pm.close();
		return resultat;
	}
	
	/**
	 * Obtention des administrateurs
	 * @return la liste administrateur ou null
	 */
	public ArrayList<Administrateur> getListAdmin() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Administrateur courrant = null;
		ArrayList<Administrateur> resultat = new ArrayList<Administrateur>();
		
		Extent<Administrateur> e = pm.getExtent(Administrateur.class,true);
		Iterator<Administrateur> it = e.iterator();
		
		while (it.hasNext()) 
		{
			courrant = (Administrateur) it.next();
			resultat.add(courrant);
		}		
		
		pm.close();
		return resultat;
	}
	
	/**
	 * Permet d'effacer tous les administrateurs de la bd
	 */
	public void removeAllAdmin() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Administrateur courrant = null;
		
		Extent<Administrateur> e = pm.getExtent(Administrateur.class,true);
		Iterator<Administrateur> it = e.iterator();
		
		while (it.hasNext()) {
			courrant = (Administrateur) it.next();
            pm.deletePersistent(courrant);
		}
		
		pm.close();
	}
	
	/**
	 * Retourne vrai si la personne est déjà inscrite faux sinon
	 * @param Creche requérant l'inscription
	 * @param Personne à inscrire
	 * @return booléen
	 */
	public boolean isRegister(Creche c, Personne pers) {
		Creche cBD = getCreche(c.getAdresse().getVille() +":"+ c.getNom());
		ArrayList<Personne> lp = cBD.getListPers();
		
		if (lp != null) {
			for (Personne pe : lp) {
				if (pe.getNom().equals(pers.getNom()) && 
					pe.getPrenom().equals(pers.getPrenom()) &&
					pe.getDate().equals(pers.getDate())) {
					
					return true;
				}
			}
		}
		
		return false;
	}
	
	/**
	 * Met à jour la liste de demande d'inscription à une crèche
	 * @param creche à mettre à jour
	 * @param personne à ajouter à la liste
	 */
	public void addPersBD(Creche c, Personne pers) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		Transaction tx = pm.currentTransaction();
		
	    try {
	    	tx.begin();
	     
	    	Creche cBD = pm.getObjectById(Creche.class, c.getKey());
	    	pers.setKey(cBD.getKey());
        	cBD.addPers(pers);
        	
	        tx.commit();
	        
	    } finally {
	        if (tx.isActive()) {
	            tx.rollback();
	        }
	        pm.close();
	    }
	}
	
	/**
	 * Permet d'effacer toutes les personnes de la bd
	 */
	public void removeAllPers() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Personne courrante = null;
		
		Extent<Personne> e = pm.getExtent(Personne.class,true);
		Iterator<Personne> it = e.iterator();
		
		while (it.hasNext()) {
			courrante = (Personne) it.next();
            pm.deletePersistent(courrante);
		}
		
		pm.close();
	}
	
	/**
	 * Retourne vrai si la personne est déjà inscrite faux sinon
	 * @param Creche requérant l'inscription
	 * @param Personne à inscrire
	 * @return booléen
	 */
	public boolean removePers(Creche c, Personne pers) 
	{
		Creche cBD = getCreche(c.getNom(),c.getAdresse().getVille());
		
		if (cBD != null) {
			Persistence p = new Persistence();
			PersistenceManager pm = p.getPer();
			
			Personne courrante = null;
			
			Extent<Personne> e = pm.getExtent(Personne.class,true);
			Iterator<Personne> it = e.iterator();
			
			while (it.hasNext()) {
				courrante = (Personne) it.next();
				
				if (courrante.getNom().equals(pers.getNom()) && 
						courrante.getPrenom().equals(pers.getPrenom()) && 
						courrante.getDate().equals(pers.getDate())) {
					
					pm.deletePersistent(courrante);
					return true;
				}
	            
			}
			pm.close();
		}
		return false;
	}
	
	/**
	 * Obtention du code grâce à son code
	 * @param code recherché
	 * @return code ou null
	 */
	public Code getCode(String code) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Extent<Code> e = pm.getExtent(Code.class,true);
		Iterator<Code> it = e.iterator();
		
		while (it.hasNext()) {
			Code courrant = (Code) it.next();
			
			if (courrant.getCode().equals(code)) {
				pm.close();
				return courrant;
			}
		}
		
		pm.close();
		return null;
	}
	
	/**
	 * Supprime les codes de la bd au bout de 7 jours
	 * s'ils n'ont pas été utilisés
	 */
	public void updateCode() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Extent<Code> e = pm.getExtent(Code.class,true);
		Iterator<Code> it = e.iterator();
		
		while (it.hasNext()) {
			Code courrant = (Code) it.next();
			
			if (courrant.estPassee()) {
				pm.deletePersistent(courrant);
			}
		}
		
		pm.close();
	}
	
	/**
	 * Permet d'effacer tous les codes de la bd
	 */
	public void removeAllCode() {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Code courrant = null;
		
		Extent<Code> e = pm.getExtent(Code.class,true);
		Iterator<Code> it = e.iterator();
		
		while (it.hasNext()) {
			courrant = (Code) it.next();
            pm.deletePersistent(courrant);
		}
		
		pm.close();
	}
	
	/**
	 * Supprime de la bd le code passé en paramètre
	 * @param code
	 */
	public void removeCode(String code) {
		Persistence p = new Persistence();
		PersistenceManager pm = p.getPer();
		
		Code courrant = null;
		
		Extent<Code> e = pm.getExtent(Code.class,true);
		Iterator<Code> it = e.iterator();
		
		while (it.hasNext()) {
			courrant = (Code) it.next();
			
			if (code.equals(courrant.getCode())) {
				pm.deletePersistent(courrant);
			}
		}
		
		pm.close();
	}
}

